package com.zxy.ziems.server.websocket;

import com.alibaba.fastjson.JSON;
import com.zxy.ziems.server.message.MessageConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
@Slf4j
public class MyCustomWebSocketHandler implements WebSocketHandler {

    //存储session池
    private static Map<String, WebSocketSession> sessionPool = new ConcurrentHashMap<>();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // 连接建立后的逻辑
        log.info("连接建立成功");
        sessionPool.put(session.getId(), session);
        log.info("当前连接数（{}）", sessionPool.size());
    }

    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        // 处理接收到的消息
        log.info("接收到消息：{}", message.getPayload());
        if (message instanceof TextMessage) {
            TextMessage textMessage = (TextMessage) message;
            String payload = textMessage.getPayload();
            CustomMessage customMessage = JSON.parseObject(payload, CustomMessage.class);
            MessageConstants.WebSocketType type = MessageConstants.WebSocketType.getByType(customMessage.getType());
            if (type == null) {
                session.sendMessage(new TextMessage("不支持的消息类型"));
            } else {
                switch (type) {
                    case ALARM_RECORD:
                        // 处理告警消息
                        break;
                    case PING:
                        session.sendMessage(message);
                        break;
                    default:
                        session.sendMessage(new TextMessage("不支持的消息类型"));
                        break;
                }
            }
        } else if (message instanceof BinaryMessage) {
            // 处理二进制消息
            log.info("接收到二进制消息");
       } else if (message instanceof PingMessage) {
        }
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        // 处理传输错误
        log.error("传输错误：{}", exception.getMessage());
        if(session.isOpen()) {
            session.close();
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        // 连接关闭后的逻辑
        log.info("连接关闭，状态码：{}", closeStatus.getCode());
        sessionPool.remove(session.getId());
        log.info("当前连接数（{}）", sessionPool.size());
    }

    @Override
    public boolean supportsPartialMessages() {
        log.info("是否支持部分消息：{}", true);
        return true;
    }

    /**
     * 给所有在线用户发送消息
     * @param message
     */
    public void sendMessageToAllUser(@Payload TextMessage message) {
        log.info("通知所有用户消息==》message={}", JSON.toJSONString(message));
        sessionPool.forEach((k, v) -> {
            try {
                v.sendMessage(message);
            } catch (IOException e) {
                log.error("消息发送失败", e);
            }

        });
    }

    /**
     * 检测与客户端心跳，断开移除连接
     */
    public void checkHeartbeat() {
        sessionPool.forEach((k, v) -> {
            if (v == null || !v.isOpen()) {
                sessionPool.remove(k);
            }
        });
    }
}
